﻿using System;
using System.Collections.Generic;
using System.Linq;
using CardPlay.Model.CardModel;
using CardPlay.Model.GameModel;
using CardPlay.Model.GameModel.Actions;
using Action = CardPlay.Model.GameModel.Actions.Action;

namespace CardPlay.DemoPack.Games.FreeCellVariants
{
    public abstract class FreeCellBase : StandardCardGame
    {
        public const string FamilyName = "Free Cell";

        protected FreeCellBase()
        {
            NamesOfAdditionalPiles.Clear();

            TotalFoundations = 4;
            TableauBuildSequence = CardFaceSequence.SameSuitDescendingRank; 
        }

        protected int TotalReserves { get; set; }

        protected int TotalFreeCells
        {
            get { return PilesNamed(AnyReserve).Count(pile => pile.IsEmpty); }
        }

        protected override void OverridePlayingRules(PlayingRules playingRules)
        {
            playingRules.At(AnyReserve)
                .ConditionallyPermit<RemovePileAction>(Action.IsActingOnFaceUpTopCard)
                .ConditionallyPermit<MovePileAction>(action => action.IsMovingSingleCard() && action.TargetPile.IsEmpty);
        }

        protected override bool AllowedToPickupAtTableau(RemovePileAction action)
        {
            return action.IsActingOnFaceUpTopCard() || (action.IsActingOnFaceUpTopPileInSequence(TableauBuildSequence) && IsTableauMovePossible(action));
        }

        protected override bool AllowedToBuildEmptyTableau(MovePileAction action)
        {
            return RankSequence.AscendingRank(action.PileBeingMoved.BottomCard.Rank, FoundationBaseRank);
        }

        protected virtual bool IsTableauMovePossible(RemovePileAction action)
        {
            return action.PileBeingRemoved.Count <= TotalFreeCells + 1;
        }

        protected override IEnumerable<String> InitialPileNames
        {
            get { return base.InitialPileNames.Concat(StandardPileNames.Reserves.Take(TotalReserves)); }
        }
    }
}